package test.traffic;

import cn.legym.garp.gateway.traffic.dynamic.DynamicResourceManager;
import com.alibaba.cloud.sentinel.datasource.RuleType;
import com.alibaba.csp.sentinel.property.SentinelProperty;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSONObject;
import org.junit.Assert;
import org.junit.Test;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * create by pipisun on 2021/9/14
 * copyright © 2017-2021 Legym Technology Co.,Ltd. All rights reserve
 * d.
 * file description:
 * last update by {} on {}
 * update description:
 */
public class RuleFunctionEnumTestcase {

    @Test
    public void testFindRuleByName() {
        FlowRule rule = newFlowRule();

        DynamicResourceManager.RuleFunctionEnum funcEnum = DynamicResourceManager.RuleFunctionEnum.fromRuleType(RuleType.FLOW);
        Assert.assertEquals(rule, funcEnum.findExistingRuleByName(rule.getResource()));
    }

    @Test
    public void testInvokeRuleNameSupplier() {
        FlowRule rule = newFlowRule();

        DynamicResourceManager.RuleFunctionEnum funcEnum = DynamicResourceManager.RuleFunctionEnum.fromRuleType(RuleType.FLOW);
        Assert.assertEquals(rule.getResource(), funcEnum.invokeRuleNameSupplier(rule));

    }

    private FlowRule newFlowRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setCount(1);
        rule.setResource("test_res");
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
        return rule;
    }

    @Test
    public void testLocalRules() throws NoSuchFieldException, IllegalAccessException {
        FlowRule rule = newFlowRule();

        DynamicResourceManager.RuleFunctionEnum funcEnum = DynamicResourceManager.RuleFunctionEnum.fromRuleType(RuleType.FLOW);

        Field propertyField = FlowRuleManager.class.getDeclaredField("currentProperty");
        propertyField.setAccessible(true);
        SentinelProperty<List<FlowRule>> property = (SentinelProperty<List<FlowRule>>) propertyField.get(null);
        Object ret = funcEnum.invokeUpdateRule("$dynamic_" + rule.getResource(), JSONObject.toJSONString(rule), property);
        Assert.assertNotNull(ret);
        Assert.assertEquals(ret.getClass(), FlowRule.class);
        FlowRule retRule = (FlowRule) ret;
        Assert.assertEquals("$dynamic_" + rule.getResource(), retRule.getResource());
        Assert.assertEquals(2, FlowRuleManager.getRules().size());

        funcEnum.invalidateLocalRule(property);
        Assert.assertEquals(1, FlowRuleManager.getRules().size());
    }
}
